Чтение файла

hogwarts <- read_csv("data/hogwarts_2024.csv")
hogwarts |> head()
## # A tibble: 6 × 60
##      id house    course sex   wandCore bloodStatus result Defence against the …¹
##   <dbl> <chr>     <dbl> <chr> <chr>    <chr>        <dbl>                  <dbl>
## 1     1 Ravencl…      4 fema… unicorn… half-blood      94                     73
## 2     2 Hufflep…      5 male  phoenix… half-blood      33                     38
## 3     3 Ravencl…      4 fema… dragon … half-blood     137                     52
## 4     4 Hufflep…      2 male  phoenix… half-blood      27                     50
## 5     5 Hufflep…      2 fema… phoenix… half-blood      67                     47
## 6     6 Gryffin…      6 male  phoenix… muggle-born    126                     44
## # ℹ abbreviated name: ¹​`Defence against the dark arts exam`
## # ℹ 52 more variables: `Flying exam` <dbl>, `Astronomy exam` <dbl>,
## #   `Herbology exam` <dbl>, `Divinations exam` <dbl>, `Charms exam` <dbl>,
## #   `History of magic exam` <dbl>, `Arithmancy exam` <dbl>,
## #   `Care of magical creatures exam` <dbl>, `Muggle studies exam` <dbl>,
## #   `Study of ancient runes exam` <dbl>, `Transfiguration exam` <dbl>,
## #   `Potions exam` <dbl>, week_1 <dbl>, week_2 <dbl>, week_3 <dbl>, …
hogwarts |> glimpse()
## Rows: 560
## Columns: 60
## $ id                                   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11…
## $ house                                <chr> "Ravenclaw", "Hufflepuff", "Raven…
## $ course                               <dbl> 4, 5, 4, 2, 2, 6, 7, 5, 2, 3, 7, …
## $ sex                                  <chr> "female", "male", "female", "male…
## $ wandCore                             <chr> "unicorn hair", "phoenix feather"…
## $ bloodStatus                          <chr> "half-blood", "half-blood", "half…
## $ result                               <dbl> 94, 33, 137, 27, 67, 126, 63, 7, …
## $ `Defence against the dark arts exam` <dbl> 73, 38, 52, 50, 47, 44, 51, 47, 2…
## $ `Flying exam`                        <dbl> 33, 36, 73, 42, 41, 52, 34, 34, 2…
## $ `Astronomy exam`                     <dbl> 57, 45, 66, 49, 57, 59, 58, 37, 5…
## $ `Herbology exam`                     <dbl> 73, 50, 62, 39, 38, 46, 59, 23, 2…
## $ `Divinations exam`                   <dbl> 66, 54, 72, 42, 47, 49, 42, 38, 1…
## $ `Charms exam`                        <dbl> 60, 70, 77, 46, 35, 55, 86, 20, 4…
## $ `History of magic exam`              <dbl> 52, 36, 60, 45, 50, 40, 55, 21, 2…
## $ `Arithmancy exam`                    <dbl> 61, 36, 58, 32, 76, 50, 41, 31, 2…
## $ `Care of magical creatures exam`     <dbl> 44, 41, 70, 36, 46, 73, 29, 36, 4…
## $ `Muggle studies exam`                <dbl> 64, 34, 52, 59, 50, 54, 36, 31, 4…
## $ `Study of ancient runes exam`        <dbl> 50, 35, 59, 39, 48, 56, 47, 41, 3…
## $ `Transfiguration exam`               <dbl> 74, 70, 70, 15, 32, 86, 100, 31, …
## $ `Potions exam`                       <dbl> 67, 38, 22, 64, 56, 60, 62, 55, 1…
## $ week_1                               <dbl> 0, -5, 0, -1, 1, 5, 1, -20, 3, -2…
## $ week_2                               <dbl> -10, 1, 0, 5, 20, 10, -5, 10, 1, …
## $ week_3                               <dbl> 0, -1, 1, -5, 10, -5, 3, -5, -3, …
## $ week_4                               <dbl> 10, 1, -1, 10, -10, 10, 0, -10, -…
## $ week_5                               <dbl> 3, -5, 3, 0, -1, 20, 5, 5, -3, 5,…
## $ week_6                               <dbl> -20, 20, 0, 0, 0, 0, 0, 5, 0, -1,…
## $ week_7                               <dbl> 10, 10, 1, -3, -20, 1, 10, 3, -5,…
## $ week_8                               <dbl> 5, 5, 1, -5, 5, 5, 0, 1, 0, 20, -…
## $ week_9                               <dbl> 1, 1, 3, -1, 0, 3, -20, -20, -10,…
## $ week_10                              <dbl> 20, -10, 1, 5, -1, 0, 5, -5, 5, 3…
## $ week_11                              <dbl> 5, -10, 20, 0, 0, 0, 5, 10, 5, 5,…
## $ week_12                              <dbl> 5, -5, 1, -20, -10, -5, 0, 5, 1, …
## $ week_13                              <dbl> -20, -5, 10, 0, 0, 1, -1, 10, -20…
## $ week_14                              <dbl> 0, 5, 3, 10, -10, 20, 0, -20, -20…
## $ week_15                              <dbl> 1, 20, 1, 0, -20, 10, 1, 3, -20, …
## $ week_16                              <dbl> 20, 5, 5, 5, 0, 3, 10, -1, 5, 5, …
## $ week_17                              <dbl> 3, 0, 10, 5, 5, -5, -1, 10, -10, …
## $ week_18                              <dbl> 10, 5, 5, 5, 10, -20, 0, 10, 3, 5…
## $ week_19                              <dbl> -10, 0, -5, -1, 0, -1, 0, 20, 0, …
## $ week_20                              <dbl> 10, -10, 5, 10, 0, -1, -1, 10, 0,…
## $ week_21                              <dbl> 0, 5, 5, 3, 5, 0, 0, -5, -5, 5, 5…
## $ week_22                              <dbl> 20, -5, 5, 0, 20, 5, -1, 0, 0, 20…
## $ week_23                              <dbl> 5, 1, -3, 20, -5, 20, 0, 1, 1, 5,…
## $ week_24                              <dbl> 10, -20, -20, 0, 10, 5, 5, -3, -5…
## $ week_25                              <dbl> 0, -20, 1, 3, 5, 1, -5, 0, -20, 2…
## $ week_26                              <dbl> 10, 10, 5, -1, 0, 5, 5, -3, 0, 20…
## $ week_27                              <dbl> 5, 5, -3, 0, 20, 5, 0, -5, 10, 3,…
## $ week_28                              <dbl> -3, 20, 20, 1, 10, 5, 1, 10, 0, 1…
## $ week_29                              <dbl> -20, -5, 5, 5, -10, 1, 0, -3, 0, …
## $ week_30                              <dbl> 5, 1, -5, 5, -5, -1, -20, 20, 1, …
## $ week_31                              <dbl> 5, 5, 20, -5, -10, -3, 0, -10, 20…
## $ week_32                              <dbl> -5, 1, 20, -1, -10, 5, 10, 1, 0, …
## $ week_33                              <dbl> 0, 10, 3, 3, 0, 0, -1, 0, -20, 3,…
## $ week_34                              <dbl> 0, -1, 0, 0, 10, 3, 20, -5, 10, 3…
## $ week_35                              <dbl> 5, -5, 3, -10, 3, -5, 0, 0, 0, 0,…
## $ week_36                              <dbl> 1, 5, 1, -20, 5, 20, -1, -3, 1, 3…
## $ week_37                              <dbl> 0, 0, 10, -1, 10, 3, 3, 0, 20, 1,…
## $ week_38                              <dbl> 10, -1, 0, -5, 5, 5, 20, -5, -3, …
## $ week_39                              <dbl> 3, 5, 1, 10, 20, 0, 5, 1, -5, 0, …
## $ week_40                              <dbl> 0, 0, 5, 1, 5, 1, 10, -5, -20, 3,…
# Changing some variables type to factors
hogwarts <- hogwarts |> mutate(
  across(c(house, course, sex, wandCore, bloodStatus), ~ as.factor(.x))
)

Столбчатые диаграммы

  1. Постройте барплот (столбчатую диаграмму), отражающую распределение числа студентов по курсу обучения. Примените любую из встроенных тем ggplot. Раскрасьте столбики любым понравившимся вам цветом (можно использовать как словесные обозначения, так и гекскоды). Добавьте цвет контура столбиков. (1 б).
theme_custom <- theme(
    axis.text = element_text(size = 20),
    axis.title = element_text(size = 25),
    legend.text = element_text(size = 20),
    legend.title = element_text(size = 20)
  )


ggplot(hogwarts)+
  geom_bar(aes(x = course),
               fill = "indianred1", color = "black")+  
  theme_bw()+                                      
  theme_custom+                                   
  labs(
    title = "Распределение студентов по курсу обучения", 
    x = "Курс", 
    y = "Количество студентов"
  )

  1. Создайте новый барплот, отражающий распределение числа студентов по факультету. Добавьте на график вторую факторную переменную – происхождение (bloodStatus). Модифицируйте при помощи аргумента position графика так, чтобы каждый столбец показывал распределение факультета по чистоте крови в долях. Примените произвольную тему. Запишите текстом в rmd-документе, какой вывод можно сделать из графика? (1 б).
ggplot(hogwarts)+
  geom_bar(aes(x = house,
               fill = bloodStatus),
           position = "fill",
           color = "black")+  
  theme_bw()+                                      
  theme_custom+                                   
  labs(
    title = "Распределение студентов по факультету", 
    x = "Факультет", 
    y = "Количество в долях"
  )

Вывод: В факультетах “Hufflepuff” и “Ravenclaw” наблюдается примерно равное распределение студентов по происхождению. В “Slytherin” больше полукровных студентов по сравнению с другими факультетами и меньше всего студентов, чьи оба родителя — маглы. В “Gryffindor” самая высокая доля студентов, чьи оба родителя — маглы.

  1. Модифицируйте датасет таким образом, чтобы в нем остались только чистокровные (pure-blood) и маглорожденные студенты (muggle-born). Создайте на основе этих данных график из пункта 2. Добавьте горизонтальную пунктирную линию произвольного цвета на уровне 50%. Дайте осям название на русском языке (1б). Дополнительно: переименуйте на русский язык категории легенды pure-blood и muggle-born (0.5 б).
filtered_hogwarts <- hogwarts %>%
  filter(bloodStatus %in% c("pure-blood", "muggle-born"))

ggplot(filtered_hogwarts)+
  geom_bar(aes(x = house, 
               fill = bloodStatus),
           position = "fill",
           color = "black")+
  scale_fill_manual(
    values = c("pure-blood" = "#1f78b4", "muggle-born" = "#33a02c"),
    labels = c("pure-blood" = "Чистокровные", "muggle-born" = "Маглорожденные")
  )+
  geom_hline(yintercept = 0.5, linetype = "dashed", color = "red")+
  labs(
    title = "Распределение студентов по факультету и происхождению",
    x = "Факультет", 
    y = "Доля студентов",
    fill = "Происхождение"  # Название легенды на русском языке
  )+
  theme_bw()+                                      
  theme_custom

## Боксплоты

  1. Отобразите распределение баллов, заработанных студентами на 3-й неделе обучения, по факультетам. Отсортируйте факультеты в порядке убывания медианного балла за 3-ю неделю (мы не останавливались на этом в лекции, но упомянутая в ней функция по умолчанию сортирует именно по медиане, так что в этом случае дополнительных аргументов передавать не следует). (1 б.)
ggplot(hogwarts)+
  geom_boxplot(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                   y = `week_3`),
               fill = "indianred1", color = "black")+
  labs(
    title = "Распределение баллов на 3-й неделе обучения по факультетам",
    x = "Факультет",
    y = "Баллы на 3-й неделе"
  ) +
  theme_bw()+
  theme_custom

2. Добавьте отображение разными цветами для происхождения студентов (bloodStatus). Добавьте на боксплот вырезку (notch). Настройте для данного чанка размер изображения 14:14 дюймов. Приведите названия осей к корректному виду. (1 б.)

options(repr.plot.width = 14, repr.plot.height = 14)

ggplot(hogwarts)+
  geom_boxplot(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                   y = `week_3`, fill = bloodStatus),
               notch = TRUE, color = "black")+
  labs(
    title = "Распределение баллов на 3-й неделе обучения по факультетам",
    x = "Факультет",
    y = "Баллы на 3-й неделе"
  )+
  scale_fill_manual(
    values = c("pure-blood" = "#1f78b4", "muggle-born" = "#33a02c", "half-blood" = "indianred1"),
    labels = c("pure-blood" = "Чистокровные", "muggle-born" = "Маглорожденные", "half-blood" = "Полукровки")
  )+
  theme_bw()+
  theme_custom

3. Добавьте на график джиттер-плот. Удалите отображение выбросов у боксплота. Видоизмените по своему вкусу толщину линий и ширину боксплота. (1 б.) Дополнительно: Добавьте название графика и подпись (0.5 б.)

ggplot(hogwarts)+
  geom_boxplot(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                   y = `week_3`, fill = bloodStatus), 
               notch = TRUE, 
               color = "black", 
               outlier.shape = NA,  
               width = 0.5,         
               size = 1.5)+
  geom_jitter(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                  y = `week_3`, color = bloodStatus), 
              alpha = 0.7,           
              width = 0.15)+
  labs(
    title = "Распределение баллов на 3-й неделе обучения по факультетам",  
    x = "Факультет",                                                       
    y = "Баллы на 3-й неделе",                                             
    caption = "Данные о баллах студентов на 3-й неделе"                     
  )+
  scale_fill_manual(  
    values = c("pure-blood" = "#0072B2", "muggle-born" = "#33a02c", "half-blood" = "indianred1"),
    labels = c("pure-blood" = "Чистокровные", "muggle-born" = "Маглорожденные", "half-blood" = "Полукровки")
  )+
  scale_color_manual(  
    values = c("pure-blood" = "#0072B2", "muggle-born" = "#33a02c", "half-blood" = "indianred1")
  )+
  theme_bw()+
  theme(  
    axis.text = element_text(size = 14),
    axis.title = element_text(size = 16),
    plot.title = element_text(size = 18), 
    legend.text = element_text(size = 14),
    legend.title = element_blank()         
  )

Разное

Постройте гистограмму распредления баллов за экзамен по астрономии.Выделите цветом факультет Слизерин. Примените 18-й кегль к тексту на осях x, y и легенды. Название оси y и легенды запишите 20-м кеглем, оси x – 22-м. Измените название оси y на “Number of students”. (1 б.)

num_bins <- 20

ggplot(hogwarts) +
  geom_histogram(aes(x = `Astronomy exam`, 
                     fill = ifelse(house == "Slytherin", "Slytherin", "Other")), 
                 bins = num_bins, 
                 color = "black",    
                 alpha = 0.7) +     
  scale_fill_manual(
    values = c("Slytherin" = "darkgreen", "Other" = "lightgray"),
    labels = c("Slytherin" = "Слизерин", "Other" = "Другие факультеты")
  )+ 
  labs(title = "Распределение баллов по экзамену по астрономии", 
       x = "Баллы по астрономии", 
       y = "Number of students") +
  theme_minimal()+  
  theme(
    axis.text = element_text(size = 18),       
    axis.title.x = element_text(size = 22),    
    axis.title.y = element_text(size = 20),    
    legend.text = element_text(size = 18),    
    legend.title = element_blank()            
  )

На лекции мы использовали комбинацию theme_bw(), и созданной нами theme_custom, чтобы одновременно сделать фон белым и увеличить шрифт. Модифицируйте theme_custom таким образом, чтобы она и выполняла свои прежние функции, и делала фон белым без помощи theme_bw(). Примените новую кастомную тему к графику, полученному в последнем пункте блока по боксплотам (1.5 б).

theme_custom <- theme(
    axis.text = element_text(size = 20),
    axis.title = element_text(size = 25),
    legend.text = element_text(size = 20),
    legend.title = element_text(size = 20)
  )

theme_custom <- theme(
  panel.background = element_rect(fill = "white", colour = "white"),
  axis.text = element_text(size = 20),
  axis.title = element_text(size = 25),
  legend.text = element_text(size = 20),
  legend.title = element_text(size = 20)
)

ggplot(hogwarts)+
  geom_boxplot(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                   y = `week_3`, fill = bloodStatus), 
               notch = TRUE, color = "black", width = 0.5, outlier.shape = NA)+
  geom_jitter(aes(x = reorder(house, `week_3`, FUN = median, decreasing = TRUE), 
                   y = `week_3`, color = bloodStatus), 
               width = 0.2, size = 2, alpha = 0.8)+
  labs(
    title = "Распределение баллов на 3-й неделе обучения по факультетам", 
    x = "Факультет", 
    y = "Баллы на 3-й неделе"
  )+
  scale_fill_manual(values = c("pure-blood" = "#1f78b4", "muggle-born" = "#33a02c", "half-blood" = "indianred1"), 
                    labels = c("pure-blood" = "Чистокровные", "muggle-born" = "Маглорожденные", "half-blood" = "Полукровки"))+
  scale_color_manual(values = c("pure-blood" = "#1f78b4", "muggle-born" = "#33a02c", "half-blood" = "indianred1"))+
  theme_custom

Фасетирование

Для визуализации гистограмм лучше использовать фасетирование по строкам, так как это упрощает восприятие частоты значений, отображая каждый столбец в отдельной строке.

Для violin-plots предпочтительнее фасетирование по столбцам, так как эти графики показывают плотность распределения и могут включать несколько измерений, что делает столбцовое представление более информативным.

Постройте гистограмму для результата любого выбранного вами экзамена, кроме зельеварения. Настройте оптимальное на ваш взгляд число столбцов гистограммы. Выполните фасетирование по курсу. Постарайтесь, чтобы график был по возможности компактным. (1 б.).

num_bins <- 15

ggplot(hogwarts)+
  geom_histogram(aes(x = `Astronomy exam`, fill = factor(course)), 
                 bins = num_bins, 
                 color = "black", 
                 alpha = 0.7)+ 
  facet_wrap(~ course, ncol = 2)+
  labs(title = "Распределение баллов по экзамену по астрономии", 
       x = "Баллы по астрономии", 
       y = "Количество студентов")+ 
  theme_minimal()+
  theme(
    legend.position = "bottom",
    text = element_text(size = 12)
  )

Отобразите на одном графике распределение плотности вероятности для оценки студентов на экзамене по защите от темных искусств и на экзамене по травологии. Раскрасьте их в любые выбранные вами цвета, постарайтесь, чтобы оба распределения отображались целиком. Примените тему из 3-го пункта блока “Разное”. Сделайте фасетирование по полу (1 б.).

ggplot(hogwarts)+
  geom_density(aes(x = `Defence against the dark arts exam`, fill = "Защита от темных искусств"), 
               alpha = 0.5, color = "blue")+
  geom_density(aes(x = `Herbology exam`, fill = "Травология"), 
               alpha = 0.5, color = "green")+
  labs(title = "Распределение плотности оценок по экзаменам",
       x = "Баллы",
       y = "Плотность вероятности")+
  scale_fill_manual(values = c("Защита от темных искусств" = "blue", "Травология" = "green"))+ 
  facet_wrap(~ sex)+
  theme_minimal()+
  theme_custom